package com.itheima.service.impl;

import com.alibaba.fastjson.JSON;
import com.itheima.client.ItemClient;
import com.itheima.pojo.Result;
import com.itheima.pojo.ResultPageBean;
import com.itheima.pojo.Sku;
import com.itheima.service.SearchService;


import com.rabbitmq.tools.json.JSONUtil;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;

import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class SearchServiceImpl implements SearchService {
    private static final String INDEX_TEMPLATE ="{\n" +
            "  \"mappings\": {\n" +
            "    \"properties\": {\n" +
            "      \"id\":{\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "      \"name\":{\n" +
            "        \"type\": \"text\"\n" +
            "        , \"analyzer\": \"ik_max_word\"\n" +
            "      },\n" +
            "      \"price\":{\n" +
            "        \"type\": \"integer\"\n" +
            "      },\n" +
            "      \"num\":{\n" +
            "        \"type\": \"integer\"\n" +
            "      },\n" +
            "      \"alertNum\":{\n" +
            "        \"type\": \"integer\"\n" +
            "      },\n" +
            "      \"image\":{\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "      \"creatTime\":{\n" +
            "        \"type\": \"date\"\n" +
            "      },\n" +
            "      \"updateTime\":{\n" +
            "        \"type\": \"date\"\n" +
            "      },\n" +
            "      \"spuId\":{\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "      \"categoryId\":{\n" +
            "        \"type\": \"integer\"\n" +
            "      },\n" +
            "      \"categoryName\":{\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "      \"brandName\":{\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "      \"spec\":{\n" +
            "        \"type\": \"text\"\n" +
            "        , \"analyzer\": \"ik_max_word\"\n" +
            "      },\n" +
            "      \"saleNum\":{\n" +
            "        \"type\": \"integer\"\n" +
            "      },\n" +
            "      \"commentNum\":{\n" +
            "        \"type\": \"integer\"\n" +
            "      },\n" +
            "      \"status\":{\n" +
            "        \"type\": \"keyword\"\n" +
            "      }\n" +
            "    }\n" +
            "  }\n" +
            "}";
    @Autowired
    private RestHighLevelClient client;
    @Autowired
    private ItemClient itemClient;

    @Override
    public void creatElasticsearch() {
        try {
            Boolean sku = isExist("sku");
            if (sku!=null){
                DeleteIndexRequest request = new DeleteIndexRequest("sku");
                client.indices().delete(request,RequestOptions.DEFAULT);

            }
            CreateIndexRequest request = new CreateIndexRequest("sku");
            request.source(INDEX_TEMPLATE, XContentType.JSON);
            CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);

        } catch (IOException e) {
            e.printStackTrace();
        }





    }

    @Override
    public void init(Integer total) {
        int currentPage = 0;
        for (int i = 0;i<=total;i=i+500){
            Result page = itemClient.findByPage(500, currentPage);
        //    ResultPageBean resultPageBean=(ResultPageBean)page.getData();
            Map map = (Map) page.getData();
            List<Map<String,String>> lists =(List<Map<String,String>>) map.get("lists");

//            List<Sku> skus = BeanUtils.mapsToBeans(lists, Sku.class);

            List<Sku> skus = JSON.parseArray(JSON.toJSONString(lists), Sku.class);

            BulkRequest request = new BulkRequest();
            for (Sku sku : skus) {
                request.add(new IndexRequest("sku").id(sku.getId()).source(JSON.toJSONString(sku),XContentType.JSON));
            }
            try {
                client.bulk(request,RequestOptions.DEFAULT);
            } catch (IOException e) {
                e.printStackTrace();
            }
            currentPage++;

        }
    }

    @Override
    public List<Sku> findByKeyWord(String keyWord) {
        SearchSourceBuilder sourceBuilder =new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.matchQuery("name",keyWord))
                .from(0).size(30)
                .highlighter(new HighlightBuilder().field("name").preTags("<span id='key'>").postTags("</span>"));
        SearchRequest request = new SearchRequest("sku");
        request.source(sourceBuilder);
        SearchResponse response = null;
        try {
            response = client.search(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        SearchHits hits = response.getHits();

        SearchHit[] hitsHits = hits.getHits();
        List<Sku>skus = new ArrayList<>();
        for (SearchHit hitsHit : hitsHits) {

            String hitSourceAsString = hitsHit.getSourceAsString();
            Sku sku = JSON.parseObject(hitSourceAsString, Sku.class);
            Map<String, HighlightField> highlightFields = hitsHit.getHighlightFields();
            if (highlightFields!=null&&!highlightFields.isEmpty()){
                HighlightField name = highlightFields.get("name");
                Text[] fragments = name.getFragments();
                String join = StringUtils.join(fragments);
                sku.setName(join);
                skus.add(sku);

            }

        }
        return skus;
    }
    public Boolean isExist(String name) throws IOException {
            GetIndexRequest request = new GetIndexRequest(name);
            return client.indices().exists(request, RequestOptions.DEFAULT);


    }

}
